package com.sikaryofficial.information.service.articlesync;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.sikaryofficial.common.redis.service.RedisService;
import com.sikaryofficial.information.constant.ArticleDataSyncConstant;
import com.sikaryofficial.information.constant.DataSyncOptConstant;
import com.sikaryofficial.information.domain.dto.resp.ArticleRecommendDTO;
import com.sikaryofficial.information.domain.entity.ArticleRecommend;
import com.sikaryofficial.information.domain.mapping.ArticleMapping;
import com.sikaryofficial.information.message.body.InformationMessage;
import com.sikaryofficial.information.service.IArticleRecommendService;
import com.sikaryofficial.information.service.article.ArticleCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author : qinjinyuan
 * @desc : 文章推荐数据同步服务
 * @date : 2023/10/31 19:03
 */
@Slf4j
@Service(value = ArticleDataSyncConstant.ARTICLE_RECOMMEND + DataSyncStrategy.SUFFIX)
public class RecommendDataSyncService extends AbstractDataSyncService {
    @Autowired
    private IArticleRecommendService articleRecommendService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ArticleCache articleCache;
    /**
     * 数据同步处理
     *
     * @param message
     */
    @Override
    public void processSync(InformationMessage message) {
        /**
         * 同步类型： INSERT | DELETE
         */
        if (CharSequenceUtil.isBlank(message.getType())) {
            log.error("message.getType is null");
            return;
        }
        if (Objects.isNull(message.getUserId())) {
            log.error("message.userId is null");
            return;
        }
        if (DataSyncOptConstant.INSERT.equals(message.getType())) {
            removeSyncData(message.getArticleRecommendList());
            // 更新
            saveSyncData(message.getArticleRecommendList());
        } else {
            log.error("ArticleRecommendDataSync同步类型错误");
        }
    }

    private void removeSyncData(List<ArticleRecommendDTO> articleRecommendList) {
        try {
            // 查询userId 和 articleId 是否存在数据
            List<ArticleRecommend> articles = ArticleMapping.INSTANCE.coverToRecommendList(articleRecommendList);
            List<ArticleRecommend> allDeletedArticles = Lists.newArrayList();
            for (ArticleRecommend item : articles) {
                List<ArticleRecommend> articleRecommends =
                        articleRecommendService.list(new LambdaQueryWrapper<ArticleRecommend>()
                                .eq(ArticleRecommend::getDeletedVersion, 0L)
                                .eq(ArticleRecommend::getUserId, item.getUserId())
                                .eq(ArticleRecommend::getArticleId, item.getArticleId())
                        );
                if (CollUtil.isNotEmpty(articleRecommends)) {
                    allDeletedArticles.addAll(articleRecommends);
                }
            }
            Set<Long> articleRecommendIdSet = allDeletedArticles.stream().map(ArticleRecommend::getArticleRecommendId).collect(Collectors.toSet());
            if(CollUtil.isEmpty(articleRecommendIdSet)){
                return;
            }
            // 分批处理
            List<List<Long>> idPartition = Lists.partition(new ArrayList<>(articleRecommendIdSet), 2000);
            for (List<Long> ids : idPartition) {
                articleRecommendService.removeByIds(ids);
                log.info("removeSyncData ids,{}", ids);
            }
        } catch (Exception e) {
            log.error("removeSyncData error,{}", e);
        }
    }

    private void saveSyncData(List<ArticleRecommendDTO> articleRecommendList) {
        try {
            List<ArticleRecommend> articles = ArticleMapping.INSTANCE.coverToRecommendList(articleRecommendList);
            for (ArticleRecommend item : articles) {
                item.setUpdatedTime(new Date());
                item.setUpdatedBy(0L);
                item.setCreatedTime(Objects.isNull(item.getCreatedTime()) ? new Date() : item.getCreatedTime());
            }
            articleRecommendService.saveOrUpdateBatch(articles, 2000);
        } catch (Exception e) {
            log.error("updateSyncData error,{}", e);
        }
    }
}
